#[cfg(feature = "ssr")]
use crate::base::{Error, Result};
#[cfg(feature = "ssr")]
use clickhouse_rs::types::SqlType;
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::{Number, Value};
use std::fmt::{Display, Formatter};
#[cfg(feature = "ssr")]
use strum::{EnumIter, EnumString};

use super::report::Unit;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct FieldProps {
    pub name: String,
    pub comment: String,
    pub field_type: FieldType,
    pub is_pk: bool,
    pub is_null: bool,
    pub is_auto_incr: bool,
    pub default: Option<String>,
}
#[derive(Debug, Copy, PartialEq, Eq, Clone, Serialize, strum::Display)]
pub enum DataType {
    Bool,
    Int,
    Float,
    String,
    Date,
    Datetime,
}
impl Default for DataType {
    fn default() -> Self {
        DataType::String
    }
}
impl<'de> Deserialize<'de> for DataType {
    fn deserialize<D>(deserializer: D) -> std::result::Result<DataType, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        match s.to_lowercase().as_str() {
            "bool" => Ok(DataType::Bool),
            "int" => Ok(DataType::Int),
            "float" => Ok(DataType::Float),
            "string" => Ok(DataType::String),
            "date" => Ok(DataType::Date),
            "datetime" => Ok(DataType::Datetime),
            _ => Ok(DataType::String),
        }
    }
}
#[cfg(feature = "ssr")]
impl From<FieldType> for DataType {
    fn from(ftype: FieldType) -> Self {
        match ftype {
            FieldType::UInt8 => DataType::Int,
            FieldType::UInt16 => DataType::Int,
            FieldType::UInt32 => DataType::Int,
            FieldType::UInt64 => DataType::Int,
            FieldType::Bool => DataType::Int,
            FieldType::Int8 => DataType::Int,
            FieldType::Int16 => DataType::Int,
            FieldType::Int32 => DataType::Int,
            FieldType::Int64 => DataType::Int,
            FieldType::Float32 => DataType::Float,
            FieldType::Float64 => DataType::Float,
            FieldType::Decimal(_, _) => DataType::Float,
            FieldType::String(_) => DataType::String,
            FieldType::Date => DataType::Date,
            FieldType::Datetime => DataType::Datetime,
        }
    }
}
#[cfg(feature = "ssr")]
impl From<SqlType> for DataType {
    fn from(sql_type: SqlType) -> Self {
        match sql_type {
            SqlType::UInt8 => DataType::Int,
            SqlType::UInt16 => DataType::Int,
            SqlType::UInt32 => DataType::Int,
            SqlType::UInt64 => DataType::Int,
            SqlType::Bool => DataType::Int,
            SqlType::Int8 => DataType::Int,
            SqlType::Int16 => DataType::Int,
            SqlType::Int32 => DataType::Int,
            SqlType::Int64 => DataType::Int,
            SqlType::Float32 => DataType::Float,
            SqlType::Float64 => DataType::Float,
            SqlType::Decimal(_, _) => DataType::Float,
            SqlType::String => DataType::String,
            SqlType::Date => DataType::Date,
            SqlType::DateTime(_) => DataType::Datetime,
            SqlType::Nullable(ty) => Self::from(ty.clone()),
            _ => DataType::String,
        }
    }
}
#[derive(Debug, Copy, PartialEq, Eq, Clone, Serialize, Deserialize, strum::Display)]
pub enum FieldType {
    Bool,
    UInt8,
    UInt16,
    UInt32,
    UInt64,
    Int8,
    Int16,
    Int32,
    Int64,
    Float32,
    Float64,
    Decimal(u8, u8),
    String(u16),
    Date,
    Datetime,
}
impl Default for FieldType {
    fn default() -> Self {
        FieldType::String(50)
    }
}
impl FieldType {
    pub fn to_mysql_type(&self) -> String {
        match self {
            FieldType::UInt8 => "TINYINT UNSIGNED".to_string(),
            FieldType::UInt16 => "SMALLINT UNSIGNED".to_string(),
            FieldType::UInt32 => "INT UNSIGNED".to_string(),
            FieldType::UInt64 => "BIGINT UNSIGNED".to_string(),
            FieldType::Bool => "TINYINT UNSIGNED".to_string(),
            FieldType::Int8 => "TINYINT".to_string(),
            FieldType::Int16 => "SMALLINT".to_string(),
            FieldType::Int32 => "INT".to_string(),
            FieldType::Int64 => "BIGINT".to_string(),
            FieldType::Float32 => "FLOAT".to_string(),
            FieldType::Float64 => "DOUBLE".to_string(),
            FieldType::Decimal(p, s) => format!("DECIMAL({p},{s})"),
            FieldType::String(len) => format!("VARCHAR({len})"),
            FieldType::Date => "DATE".to_string(),
            FieldType::Datetime => "DATETIME".to_string(),
        }
    }
}

#[cfg(feature = "ssr")]
impl From<SqlType> for FieldType {
    fn from(sql_type: SqlType) -> Self {
        match sql_type {
            SqlType::UInt8 => FieldType::UInt8,
            SqlType::UInt16 => FieldType::UInt16,
            SqlType::UInt32 => FieldType::UInt32,
            SqlType::UInt64 => FieldType::UInt64,
            SqlType::Bool => FieldType::Bool,
            SqlType::Int8 => FieldType::Int8,
            SqlType::Int16 => FieldType::Int16,
            SqlType::Int32 => FieldType::Int32,
            SqlType::Int64 => FieldType::Int64,
            SqlType::Float32 => FieldType::Float32,
            SqlType::Float64 => FieldType::Float64,
            SqlType::Decimal(p, s) => FieldType::Decimal(p, s),
            SqlType::String => FieldType::String(50),
            SqlType::Date => FieldType::Date,
            SqlType::DateTime(_) => FieldType::Datetime,
            SqlType::Nullable(ty) => Self::from(ty.clone()),
            _ => FieldType::String(50),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct WhereCauses(Vec<WhereCause>);
impl AsRef<Vec<WhereCause>> for WhereCauses {
    #[inline]
    fn as_ref(&self) -> &Vec<WhereCause> {
        &self.0
    }
}
impl AsMut<Vec<WhereCause>> for WhereCauses {
    #[inline]
    fn as_mut(&mut self) -> &mut Vec<WhereCause> {
        &mut self.0
    }
}
impl WhereCauses {
    pub fn from(wcs: Vec<WhereCause>) -> Self {
        WhereCauses(wcs)
    }
    pub fn merge(&mut self, wcs: WhereCauses) {
        self.0.extend(wcs.0);
    }
    pub fn get_by_name(&self,name:&str) -> Option<&WhereCause> {
        if self.0.is_empty() {
            None
        } else {
            self.0.iter().find(|wc| wc.field_name == name)
        }
    }
    pub fn to_join_string(&self) -> String {
        let res = serde_json::to_string(self);
        res.unwrap_or_else(|_| String::from("{}"))
    }
    pub fn get_cause_by_field_name(&self, field_name: &str) -> Option<&WhereCause> {
        self.0.iter().find(|wc| wc.field_name == field_name)
    }
    #[cfg(feature = "ssr")]
    pub fn to_where_string(
        &self,
        db_type: DbType,
        cols: &[(&str, DataType, &Unit, bool)],
    ) -> String {
        let mut s = String::new();
        for (i, wc) in self.0.iter().enumerate() {
            let (dt, unit, is_null) = cols
                .iter()
                .find(|c| c.0 == wc.field_name)
                .map(|c| (c.1, c.2, c.3))
                .unwrap_or((DataType::String, &Unit::Yuan, false));
            let wc_str = wc.to_where_string(db_type, dt, unit, is_null, None);
            s.push_str(&wc_str);
            if i + 1 < self.0.len() {
                s.push_str(" and ");
            }
        }
        s
    }
    pub fn extend(&mut self, wcs: Vec<WhereCause>) {
        self.0.extend(wcs);
    }
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct OrderItems(Vec<OrderItem>);
impl AsRef<Vec<OrderItem>> for OrderItems {
    #[inline]
    fn as_ref(&self) -> &Vec<OrderItem> {
        &self.0
    }
}
impl OrderItems {
    pub fn from(ords: Vec<OrderItem>) -> Self {
        OrderItems(ords)
    }
    pub fn get_item_by_field_name(&self, field_name: &str) -> Option<&OrderItem> {
        self.0.iter().find(|oi| oi.field_name == field_name)
    }
    pub fn to_join_string(&self) -> String {
        let res = serde_json::to_string(self);
        res.unwrap_or_else(|_| String::from("{}"))
    }
    pub fn to_order_string(&self) -> String {
        let mut s = String::new();
        for (i, item) in self.0.iter().enumerate() {
            let ostr = item.to_order_string(None);
            s.push_str(&ostr);
            if i + 1 < self.0.len() {
                s.push_str(",");
            }
        }
        s
    }
}
#[cfg(feature = "ssr")]
impl OrderItems {
    pub fn from_field(field_name: impl Into<String>, direction: Direction) -> Self {
        let ords = vec![OrderItem {
            field_name: field_name.into(),
            direction,
        }];
        OrderItems(ords)
    }
    pub fn add_order_item(
        &mut self,
        field_name: impl Into<String>,
        direction: Direction,
    ) -> &mut Self {
        self.0.push(OrderItem {
            field_name: field_name.into(),
            direction,
        });
        self
    }
}
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub enum DbType {
    MySql,
    Cilckhouse,
}
impl Default for DbType {
    fn default() -> Self {
        DbType::MySql
    }
}
impl DbType {
    pub fn to_default_value(&self, ft: DataType, is_null: bool) -> String {
        if is_null {
            return "IS NULL".to_string();
        }
        match ft {
            DataType::Bool => "0".to_string(),
            DataType::Int => "0".to_string(),
            DataType::Float => "0.0".to_string(),
            DataType::Date => "1970-01-01".to_string(),
            DataType::Datetime => "1900-01-01".to_string(),
            DataType::String => "''".to_string(),
        }
    }
}
#[derive(Debug, Clone)]
pub enum DictKeyValue {
    Keys(Vec<String>),
    Table(String),
}

/** 查询项目 */
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct FliterItem {
    /** 关系符 */
    pub operator: Operator,
    /** 字段值 */
    pub value: Option<String>,
}
impl FliterItem {
    pub(crate) fn to_where_string(
        &self,
        name: &str,
        db_type: DbType,
        dt: DataType,
        unit: &Unit,
        is_null: bool,
        filter_value: Option<&DictKeyValue>,
    ) -> String {
        if let Some(fval) = filter_value {
            match fval {
                DictKeyValue::Keys(keys) => {
                    return format!("`{}` in ({})", name, keys.join(","));
                }
                DictKeyValue::Table(table) => {
                    return format!("`{}` in (select `key_value` from {})", name, table);
                }
            }
        }
        let to_val = || {
            let mut is_str = false;
            let val = self
                .value
                .as_ref()
                .map(|v| match dt {
                    DataType::Bool => v.to_owned(),
                    DataType::Int => {
                        let v = v.parse::<i64>().unwrap_or(0);
                        let v = v * unit.to_u32() as i64;
                        v.to_string()
                    }
                    DataType::Float => {
                        let v = v.parse::<f64>().unwrap_or(0.0);
                        let v = v * (unit.to_u32() as f64);
                        v.to_string()
                    }
                    _ => {
                        let op=self.operator;
                        if op == Operator::Like || op == Operator::NotLike
                            || op == Operator::LeftLike || op == Operator::NotLeftLike
                            || op == Operator::RightLike || op == Operator::NotRightLike
                        {
                            is_str = false;
                        }else{
                            is_str = true;
                        }
                        format!("{}", v)
                    }
                })
                .unwrap_or(db_type.to_default_value(dt, is_null));
            if is_str {
                format!("'{}'", val)
            } else {
                val
            }
        };
        match self.operator {
            Operator::Eq | Operator::Null=> {
                let v = to_val();
                if v == "IS NULL" {
                    format!("`{}` IS NULL", name)
                } else {
                    format!("`{}` = {}", name, v)
                }
            }
            Operator::NotEq | Operator::NotNull=> {
                let v = to_val();
                if v == "IS NULL" {
                    format!("`{}` IS NOT NULL", name)
                } else {
                    format!("`{}` != {}", name, v)
                }
            }
            Operator::In | Operator::NotIn => {
                let mut nval = String::new();
                if self.value.is_none() {
                    if self.operator == Operator::In {
                        return format!("`{}` IS NULL", name);
                    } else {
                        return format!("`{}` IS NOT NULL", name);
                    }
                }
                let val = self.value.as_ref().unwrap();
                let vals: Vec<&str> = if val.contains(',') {
                    val.split(',').collect()
                } else if val.contains('|') {
                    val.split('|').collect()
                } else {
                    vec![val]
                };
                for iv in vals.iter() {
                    if dt == DataType::String || dt == DataType::Date || dt == DataType::Datetime {
                        nval.push_str("'");
                        nval.push_str(iv);
                        nval.push_str("'");
                    } else {
                        nval.push_str(iv);
                    }
                    nval.push_str(",");
                }
                if nval.is_empty() {
                    if self.operator == Operator::In {
                        return format!("`{}` IS NULL", name);
                    } else {
                        return format!("`{}` IS NOT NULL", name);
                    }
                } else {
                    nval.pop();
                }
                if self.operator == Operator::In {
                    format!("`{}` IN ({nval})", name)
                } else {
                    format!("`{}` NOT IN ({nval})", name)
                }
            }
            Operator::Gt => format!("`{}` > {}", name, to_val()),
            Operator::Gte => format!("`{}` >= {}", name, to_val()),
            Operator::Lt => format!("`{}` < {}", name, to_val()),
            Operator::Lte => format!("`{}` <= {}", name, to_val()),
            Operator::Like => format!("`{}` like '%{}%'", name, to_val()),
            Operator::NotLike => format!("`{}` not like '%{}%'", name, to_val()),
            Operator::LeftLike => format!("`{}` like '{}%'", name, to_val()),
            Operator::NotLeftLike => format!("`{}` not like '{}%'", name, to_val()),
            Operator::RightLike => format!("`{}` like '%{}'", name, to_val()),
            Operator::NotRightLike => format!("`{}` not like '%{}'", name, to_val()),
        }
    }
}
/** 查询条件 */
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct FliterItems {
    /** 查询项目数组 */
    pub filter_items: Vec<FliterItem>,
    /** 查询项目之间的关系 */
    #[serde(default)]
    pub and_or: AndOr,
}
impl Display for FliterItems {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let mut s = String::new();
        let len = self.filter_items.len();
        for (i, item) in self.filter_items.iter().enumerate() {
            let val = item
                .value
                .as_ref()
                .map(|v| if v.is_empty() { "空值" } else { v.as_str() })
                .unwrap_or("空值");
            s.push_str(&format!(r#"{}"{}" "#, item.operator, val));
            if i + 1 < len {
                if self.and_or == AndOr::And {
                    s.push_str("并且 ");
                } else {
                    s.push_str("或者 ");
                }
            }
        }
        write!(f, "{}", s)
    }
}
/** 查询条件 */
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct WhereCause {
    /** 字段名称 */
    pub field_name: String,
    /** 查询项目数组 */
    pub filter_items: Vec<FliterItem>,
    /** 查询项目之间的关系 */
    #[serde(default)]
    pub and_or: AndOr,
}
impl Display for WhereCause {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let mut s = String::new();
        let len = self.filter_items.len();
        for (i, item) in self.filter_items.iter().enumerate() {
            let val = item
                .value
                .as_ref()
                .map(|v| if v.is_empty() { "空值" } else { v.as_str() })
                .unwrap_or("空值");
            s.push_str(&format!(r#"{}"{}" "#, item.operator, val));
            if i + 1 < len {
                if self.and_or == AndOr::And {
                    s.push_str("并且 ");
                } else {
                    s.push_str("或者 ");
                }
            }
        }
        write!(f, "{}", s)
    }
}
impl WhereCause {
    pub fn new(field_name: String, and_or: AndOr) -> Self {
        WhereCause {
            field_name,
            filter_items: Vec::new(),
            and_or,
        }
    }
    pub fn from(field_name: String, fliter_items: Vec<FliterItem>, and_or: AndOr) -> Self {
        WhereCause {
            field_name,
            filter_items: fliter_items,
            and_or,
        }
    }
    pub fn from_filter_item(
        field_name: impl Into<String>,
        operator: Operator,
        value: Option<String>,
    ) -> Self {
        let item = FliterItem { operator, value };
        WhereCause {
            field_name: field_name.into(),
            filter_items: vec![item],
            and_or: AndOr::And,
        }
    }
    #[cfg(feature = "ssr")]
    pub fn to_where_string(
        &self,
        db_type: DbType,
        data_type: DataType,
        unit: &Unit,
        is_null: bool,
        filter_value: Option<&DictKeyValue>,
    ) -> String {
        let mut s = String::new();
        for (i, item) in self.filter_items.iter().enumerate() {
            let fname = self.field_name.as_str();
            let wc = item.to_where_string(fname, db_type, data_type, unit, is_null, filter_value);
            s.push_str(&wc);
            if i + 1 < self.filter_items.len() {
                if self.and_or == AndOr::And {
                    s.push_str(" and ");
                } else {
                    s.push_str(" or ");
                }
            }
        }
        s
    }
    #[cfg(feature = "ssr")]
    pub fn parse(&self, fps: &Vec<FieldProps>, table_name: &str) -> Result<()> {
        use crate::page_conf::valid_val_by_field_type;
        let mut is_ok = false;
        for fp in fps.iter() {
            if fp.name == self.field_name {
                is_ok = true;
                for fi in self.filter_items.iter() {
                    if let Some(val) = fi.value.as_ref() {
                        valid_val_by_field_type(fp.field_type, val).or_else(|err| {
                            Err(Error::Conf(format!(
                                "list_props-seeks-field_name的配置字段名{}的fliter_items的value值{}不是有效的{}: {}",
                                self.field_name, val, fp.field_type, err
                            )))
                        })?;
                    }
                }
            }
        }
        if !is_ok {
            return Err(Error::Conf(format!(
                "list_props-seeks-field_name的配置字段名{}在表{}不存在",
                self.field_name, table_name
            )));
        }
        Ok(())
    }
    pub fn is_ok(&self, value: &Value) -> bool {
        let mut is_ok = true;
        for item in self.filter_items.iter() {
            let val2 = item.value.as_ref().map(|v| v.as_str());
            match value {
                Value::Null => {
                    is_ok = item.operator == Operator::Eq
                        && val2.map(|v| v.is_empty()).unwrap_or(true)
                        || item.operator == Operator::NotEq
                            && val2.map(|v| !v.is_empty()).unwrap_or(false);
                }
                Value::Bool(v) => {
                    let v2 = val2
                        .map(|v| v.parse::<bool>().unwrap_or(false))
                        .unwrap_or(false);
                    is_ok = item.operator == Operator::Eq && *v == v2
                        || item.operator == Operator::NotEq && *v != v2;
                }
                Value::Number(nv) => {
                    is_ok = num_fit_cond(nv, item.operator.clone(), val2);
                }
                Value::String(sv) => is_ok = str_fit_cond(sv, item.operator.clone(), val2),
                Value::Array(_) | Value::Object(_) => is_ok = false,
            }
            if self.and_or == AndOr::And && !is_ok {
                break;
            } else if self.and_or == AndOr::Or && is_ok {
                break;
            }
        }
        is_ok
    }
    pub fn add_filter_item(&mut self, operator: Operator, value: Option<String>) {
        self.filter_items.push(FliterItem { operator, value })
    }
    pub fn is_in(&self) -> bool {
        if self.filter_items.len() == 1 {
            let oper = self.filter_items[0].operator;
            oper == Operator::In || oper == Operator::NotIn
        } else {
            false
        }
    }
    pub fn is_none(&self) -> bool {
        if self.filter_items.len() >= 1 {
            self.filter_items[0].value.is_none()
        } else {
            false
        }
    }
}

fn compare<T: PartialEq + Eq + PartialEq + Ord>(oper: Operator, v1: T, v2: T) -> bool {
    match oper {
        Operator::Eq => v1 == v2,
        Operator::NotEq => v1 != v2,
        Operator::Gt => v1 > v2,
        Operator::Gte => v1 >= v2,
        Operator::Lt => v1 < v2,
        Operator::Lte => v1 <= v2,
        _ => false,
    }
}

fn f64_compare(oper: Operator, a: f64, b: f64) -> bool {
    let eq = (a - b).abs() < f64::EPSILON;
    match oper {
        Operator::Eq => eq,
        Operator::NotEq => !eq,
        Operator::Gt => !eq && a > b,
        Operator::Gte => eq || a > b,
        Operator::Lt => !eq && a < b,
        Operator::Lte => eq || a < b,
        _ => false,
    }
}

fn num_fit_cond(val: &Number, oper: Operator, val2: Option<&str>) -> bool {
    if val2.is_none() {
        return false;
    }
    let val2 = val2.unwrap();
    match oper {
        Operator::Eq
        | Operator::NotEq
        | Operator::Gt
        | Operator::Gte
        | Operator::Lt
        | Operator::Lte => {
            if val2.contains(".") {
                let v2 = val2.parse::<f64>().ok();
                f64_compare(oper, val.as_f64().unwrap_or(0.0), v2.unwrap_or(0.0))
            } else if val2.contains("-") {
                let v2 = val2.parse::<i64>().ok();
                compare(oper, val.as_i64().unwrap_or(0), v2.unwrap_or(0))
            } else {
                let v2 = val2.parse::<u64>().ok();
                compare(oper, val.as_u64().unwrap_or(0), v2.unwrap_or(0))
            }
        }
        _ => {
            let val1 = val.to_string();
            str_fit_cond(&val1, oper, Some(val2))
        }
    }
}

fn str_fit_cond(val: &str, oper: Operator, val2: Option<&str>) -> bool {
    let val2 = val2.unwrap_or("");
    match oper {
        Operator::Eq => val == val2,
        Operator::NotEq => val != val2,
        Operator::In => val2.split(",").any(|v| v == val),
        Operator::NotIn => !val2.split(",").any(|v| v == val),
        Operator::Gt => val > val2,
        Operator::Gte => val >= val2,
        Operator::Lt => val < val2,
        Operator::Lte => val <= val2,
        Operator::Like => val.contains(val2),
        Operator::NotLike => !val.contains(val2),
        Operator::LeftLike => val.starts_with(val2),
        Operator::NotLeftLike => !val.starts_with(val2),
        Operator::RightLike => val.ends_with(val2),
        Operator::NotRightLike => !val.ends_with(val2),
        Operator::Null => val.is_empty(),
        Operator::NotNull => !val.is_empty(),
    }
}

/** 排序项目 */
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct OrderItem {
    /** 字段名称 */
    pub field_name: String,
    /** 排序方向 */
    #[serde(default)]
    pub direction: Direction,
}

impl OrderItem {
    pub fn new(field_name: String, direction: Direction) -> Self {
        Self {
            field_name,
            direction,
        }
    }
    pub fn to_join_string(&self) -> String {
        let res = serde_json::to_string(self);
        res.unwrap_or_else(|_| String::from("{}"))
    }
    #[cfg(feature = "ssr")]
    pub fn parse(&self, fps: &Vec<FieldProps>, table_name: &str) -> Result<()> {
        let is_ok = fps.iter().any(|f| f.name == self.field_name);
        if !is_ok {
            return Err(Error::Conf(format!(
                "list_props-init_sorter-field_name的配置字段名{}在表{}不存在",
                self.field_name, table_name
            )));
        }
        Ok(())
    }
    pub fn to_order_string(&self, filter_value: Option<&DictKeyValue>) -> String {
        if let Some(fval) = filter_value {
            let fname = self.field_name.as_str();
            match fval {
                DictKeyValue::Keys(keys) => {
                    return format!("FIELD(`{}`,{})", fname, keys.join(","));
                }
                DictKeyValue::Table(table) => {
                    return format!("`{table}`.id");
                }
            }
        }
        let direction = if self.direction == Direction::Asc {
            "ASC"
        } else {
            "DESC"
        };
        format!("`{}` {}", self.field_name, direction)
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub enum AndOr {
    And,
    Or,
}
impl Default for AndOr {
    fn default() -> Self {
        AndOr::And
    }
}
impl Display for AndOr {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            AndOr::And => write!(f, "and"),
            AndOr::Or => write!(f, "or"),
        }
    }
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub enum Direction {
    Asc,
    Desc,
}
impl Default for Direction {
    fn default() -> Self {
        Direction::Asc
    }
}
impl Display for Direction {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            Direction::Asc => write!(f, "升序"),
            Direction::Desc => write!(f, "降序"),
        }
    }
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, Hash)]
pub enum Operator {
    Eq,
    NotEq,
    In,
    NotIn,
    Gt,
    Gte,
    Lt,
    Lte,
    Like,
    NotLike,
    LeftLike,
    NotLeftLike,
    RightLike,
    NotRightLike,
    Null,
    NotNull
}
impl Default for Operator {
    fn default() -> Self {
        Operator::Like
    }
}
impl Display for Operator {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Operator::Eq => write!(f, "等于"),
            Operator::NotEq => write!(f, "不等于"),
            Operator::In => write!(f, "包含"),
            Operator::NotIn => write!(f, "不包含"),
            Operator::Gt => write!(f, "大于"),
            Operator::Gte => write!(f, "大于等于"),
            Operator::Lt => write!(f, "小于"),
            Operator::Lte => write!(f, "小于等于"),
            Operator::Like => write!(f, "包含"),
            Operator::NotLike => write!(f, "不包含"),
            Operator::LeftLike => write!(f, "开头是"),
            Operator::NotLeftLike => write!(f, "开头不是"),
            Operator::RightLike => write!(f, "结尾是"),
            Operator::NotRightLike => write!(f, "结尾不是"),
            Operator::Null => write!(f, "为空"),
            Operator::NotNull => write!(f, "不为空"),
        }
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "ssr", derive(EnumString, EnumIter))]
pub enum ImportMode {
    //InsertAndUpdate 有则更新、无则插入
    InsertAndUpdate,
    //DeleteAfterInsert 先按照参数删除再插入
    DeleteAfterInsert,
    //InsertOnly 仅插入
    InsertOnly,
}
